<?php
//微信绑定服务器
function wechat_bind() {
	$wechat_config = wechat_config();
	$timestamp = $_GET["timestamp"];
	$nonce = $_GET["nonce"];
	$signature = $_GET["signature"];
	if ($timestamp && $nonce && $signature) {
		$tmpArr = array($wechat_config['wechat_token'], $timestamp, $nonce);
		sort($tmpArr, SORT_STRING);
		$tmpStr = sha1(implode( $tmpArr ));
		if ($tmpStr == $signature) {
			echo $_GET["echostr"];
		}
		die();
	}
}

//微信xml格式数据
function wechat_xml($arr) {
	$xml = "<xml>";
	foreach ($arr as $k => $v) {
		if (is_numeric($v)) {
			$xml .= "<{$k}>{$v}</{$k}>";
		}
		else{
			$xml .= "<{$k}><![CDATA[{$v}]]></{$k}>";
		}
    }
    $xml .= "</xml>";
	return $xml;
}

//接收微信xml数据
function wechat_getxml() {
	return pe_getxml();
}

//发送微信xml数据
function wechat_sendxml($url, $arr, $cert = false) {
	global $pe;
	$xml = wechat_xml($arr);
	if ($cert) {
		$cert_arr['ssl_cert'] = "{$pe['path']}include/plugin/payment/wxpay/cert/apiclient_cert.pem";
		$cert_arr['ssl_key'] = "{$pe['path']}include/plugin/payment/wxpay/cert/apiclient_key.pem";		
	}
    return pe_curl_post($url, $xml, 'str', $cert_arr);
	//return json_decode(json_encode(simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
}

//发送微信post数据
function wechat_curlpost($url, $arr, $type = 'arr') {
	$result = pe_curl_post($url, $arr, $type);
	return json_decode($result, true);
}

//发送微信get数据
function wechat_curlget($url) {
	return pe_curl_get($url);
}

//生成微信参数签名
function wechat_sign($arr, $key) {
	if (!is_array($arr)) return '';
	//签名步骤一：按字典序排序参数
	ksort($arr);
	$sign = "";
	foreach ($arr as $k => $v) {
		if ($k != "sign" && $v != "" && !is_array($v)){
			$sign .= "{$k}={$v}&";
		}
	}
	$sign = trim($sign, "&");
	//签名步骤二：在string后加入KEY
	$sign = "{$sign}&key={$key}";
	//签名步骤三：MD5加密
	$sign = md5($sign);
	//签名步骤四：所有字符转为大写
	$result = strtoupper($sign);
	return $result;
}

//获取微信基础配置信息
function wechat_config($update = false) {
	global $db, $pe, $cache_setting;
	if (is_file("{$pe['path']}data/cache/wechat_config.cache.php")) {
		$wechat_config = cache::get("wechat_config");	
	}
	if ($wechat_config['time'] <= time() - 3600 || $update) {
		$wechat_config = array();
		$wechat_config['wechat_appid'] = $cache_setting['wechat_appid'];
		$wechat_config['wechat_appsecret'] = $cache_setting['wechat_appsecret'];
		$wechat_config['wechat_token'] = $cache_setting['wechat_token'];
		$wechat_config['minapp_appid'] = $cache_setting['minapp_appid'];
		$wechat_config['minapp_appsecret'] = $cache_setting['minapp_appsecret'];
		//获取公众号access_token
		$json = wechat_curlget("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$wechat_config['wechat_appid']}&secret={$wechat_config['wechat_appsecret']}");
		$json = json_decode($json, true);
		$wechat_config['wechat_access_token'] = $json['access_token'];
		//获取公众号jsapi_ticket
		$json = wechat_curlget("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$wechat_config['wechat_access_token']}&type=jsapi");
		$json = json_decode($json, true);
		$wechat_config['wechat_jsapi_ticket'] = $json['ticket'];
		//获取小程序access_token
		$json = wechat_curlget("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$wechat_config['minapp_appid']}&secret={$wechat_config['minapp_appsecret']}");
		$json = json_decode($json, true);
		$wechat_config['minapp_access_token'] = $json['access_token'];
		$wechat_config['time'] = time();
		cache::write("wechat_config", $wechat_config);
	}
	//获取微信支付信息
	$cache_payment = cache::get('payment');
	$payment = $cache_payment['wxpay']['payment_config'];
	$wechat_config['wxpay_appid'] = $payment['wxpay_appid'];
	$wechat_config['wxpay_minapp_appid'] = $payment['wxpay_minapp_appid'];
	$wechat_config['wxpay_mchid'] = $payment['wxpay_mchid'];		
	$wechat_config['wxpay_apikey'] = $payment['wxpay_apikey'];
	$wechat_config['notify_url'] = "{$pe['host']}include/plugin/payment/wxpay/notify_url.php";
	$wechat_config['refund_url'] = "{$pe['host']}include/plugin/payment/wxpay/refund_url.php";
	return $wechat_config;
}

//设置微信自定义菜单
function wechat_setmenu($json = '') {
	global $db;
	$wechat_config = wechat_config();
	if ($json) {
		//$json = preg_replace_callback("|(http://[^(\"\|')]+)|", "wechat_menuurl", $json);
		wechat_curlpost("https://api.weixin.qq.com/cgi-bin/menu/create?access_token={$wechat_config['wechat_access_token']}", $json);	
	}
}

//微信支付（pc扫码）
function wechat_pcpay($pay_id) {
	global $db, $pe;
	$wechat_config = wechat_config();
	$pay = $db->pe_select('pay', array('pay_id'=>pe_dbhold($pay_id)));
	if ($pay['order_state'] != 'wpay') {
		return array('code'=>0, 'msg'=>'请勿重复支付');		
	}
	//统一下单接口
	$xml_arr['appid'] = $wechat_config['wxpay_appid'];
	$xml_arr['mch_id'] = $wechat_config['wxpay_mchid'];
	$xml_arr['device_info'] = 'WEB';
	$xml_arr['nonce_str'] = md5(microtime(true).pe_ip().'koyshe+andrea');
	$xml_arr['body'] = pe_cut($pay['order_name'], 15, '...');
	$xml_arr['out_trade_no'] = "{$pay['pay_id']}_".rand(100,999);
	$xml_arr['total_fee'] = $pay['order_money']*100;
	$xml_arr['spbill_create_ip'] = pe_ip();
	$xml_arr['notify_url'] = $wechat_config['notify_url'];
	$xml_arr['trade_type'] = 'NATIVE';
	$xml_arr['sign'] = wechat_sign($xml_arr, $wechat_config['wxpay_apikey']);
	//发送xml下单请求
	$json = wechat_sendxml('https://api.mch.weixin.qq.com/pay/unifiedorder', $xml_arr);
	if ($json['return_code'] == 'SUCCESS' && $json['result_code'] == 'SUCCESS') {
		pe_lead('include/class/phpqrcode.class.php');
		QRcode::png($json['code_url'], "{$pe['path']}data/attachment/qrcode/{$pay_id}.png", 'QR_ECLEVEL_L', 9);	
		return array('code'=>1, 'qrcode'=>"{$pe['host']}data/attachment/qrcode/{$pay_id}.png");
	}
	else {
		return array('code'=>0, 'msg'=>"{$json['return_msg']}");
	}
}

//微信支付（h5支付）
function wechat_h5pay($pay_id) {
	global $db, $pe;
	$wechat_config = wechat_config();
	$pay = $db->pe_select('pay', array('pay_id'=>pe_dbhold($pay_id)));
	if ($pay['order_state'] != 'wpay') {
		return array('code'=>0, 'msg'=>'请勿重复支付');		
	}
	//统一下单接口
	$xml_arr['appid'] = $wechat_config['wxpay_appid'];
	$xml_arr['mch_id'] = $wechat_config['wxpay_mchid'];
	$xml_arr['device_info'] = 'WEB';
	$xml_arr['nonce_str'] = md5(microtime(true).pe_ip().'koyshe+andrea');
	$xml_arr['body'] = pe_cut($pay['order_name'], 15, '...');
	$xml_arr['out_trade_no'] = "{$pay['pay_id']}_".rand(100,999);
	$xml_arr['total_fee'] = $pay['order_money']*100;
	$xml_arr['spbill_create_ip'] = pe_ip();
	$xml_arr['notify_url'] = $wechat_config['notify_url'];
	$xml_arr['trade_type'] = 'MWEB';
	$xml_arr['scene_info'] = '{"h5_info": {"type":"Wap","wap_url": "'.$pe['host'].'","wap_name": "微信-支付"}}';
	$xml_arr['sign'] = wechat_sign($xml_arr, $wechat_config['wxpay_apikey']);
	//发送xml下单请求
	$json = wechat_sendxml('https://api.mch.weixin.qq.com/pay/unifiedorder', $xml_arr);
	if ($json['return_code'] == 'SUCCESS' && $json['result_code'] == 'SUCCESS') {
		return array('code'=>1, 'data'=>array('url'=>$json['mweb_url'], 'jump'=>pay_jump($pay_id)));
	}
	else {
		return array('code'=>0, 'msg'=>"{$json['return_msg']}");
	}
}

//微信支付（公众号/小程序）
function wechat_jspay($pay_id, $minapp = false) {
	global $db, $pe, $user;
	$wechat_config = wechat_config();
	$pay = $db->pe_select('pay', array('pay_id'=>pe_dbhold($pay_id)));
	if ($pay['order_state'] != 'wpay') {
		return array('code'=>0, 'msg'=>'请勿重复支付');		
	}
	//统一下单接口
	$xml_arr['appid'] = $minapp ? $wechat_config['wxpay_minapp_appid'] : $wechat_config['wxpay_appid'];
	$xml_arr['mch_id'] = $wechat_config['wxpay_mchid'];
	$xml_arr['device_info'] = 'WEB';
	$xml_arr['nonce_str'] = md5(microtime(true).pe_ip().'koyshe+andrea');
	$xml_arr['body'] = pe_cut($pay['order_name'], 13, '...');
	$xml_arr['out_trade_no'] = "{$pay['pay_id']}_".rand(100,999);
	$xml_arr['total_fee'] = $pay['order_money']*100;
	$xml_arr['spbill_create_ip'] = pe_ip();
	$xml_arr['notify_url'] = $wechat_config['notify_url'];
	$xml_arr['trade_type'] = 'JSAPI';
	$xml_arr['openid'] = $minapp ? $user['user_minapp_openid'] : $user['user_wx_h5_openid'];
	$xml_arr['sign'] = wechat_sign($xml_arr, $wechat_config['wxpay_apikey']);
	//发送xml下单请求
	$json = wechat_sendxml('https://api.mch.weixin.qq.com/pay/unifiedorder', $xml_arr);
	if ($json['return_code'] == 'SUCCESS' && $json['result_code'] == 'SUCCESS') {
		$payinfo['appId'] = $json['appid'];
		$payinfo['timeStamp'] = strval(time());
		$payinfo['nonceStr'] = md5(microtime(true).pe_ip().'koyshe+andrea');
		$payinfo['package'] = "prepay_id={$json['prepay_id']}";
		$payinfo['signType'] = 'MD5';
		$payinfo['paySign'] = wechat_sign($payinfo, $wechat_config['wxpay_apikey']);		
		return array('code'=>1, 'data'=>array('payinfo'=>$payinfo, 'url'=>pay_jump($pay_id)));
	}
	else {
		return array('code'=>0, 'msg'=>"{$json['return_msg']},{$json['err_code_des']}");
	}
}

//微信转账功能
function wechat_transfer($cashout_id) {
	global $db, $pe;
	$wechat_config = wechat_config();
	$cashout = $db->pe_select('cashout', array('cashout_id'=>$cashout_id));
	if ($cashout['cashout_state']) {
		return array('code'=>0, 'msg'=>'提现已处理，请勿重复审核');
	}
	//统一下单接口
	$xml_arr['mch_appid'] = $wechat_config['wxpay_appid'] ? $wechat_config['wxpay_appid'] : $wechat_config['wxpay_minapp_appid'];
	$xml_arr['mchid'] = $wechat_config['wxpay_mchid'];
	$xml_arr['nonce_str'] = md5(microtime(true).pe_ip().'koyshe+andrea');
	$xml_arr['partner_trade_no'] = $cashout['cashout_id'];
	$xml_arr['openid'] = $cashout['user_wx_openid'];
	$xml_arr['check_name'] = 'NO_CHECK';
	$xml_arr['amount'] = $cashout['cashout_money']*100;	
	$xml_arr['desc'] = '平台提现结算';
	$xml_arr['spbill_create_ip'] = pe_ip();
	$xml_arr['sign'] = wechat_sign($xml_arr, $wechat_config['wxpay_apikey']);
	//发送xml下单请求
	$json = wechat_sendxml('https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers', $xml_arr, true);
	if ($json['return_code'] == 'SUCCESS' && $json['result_code'] == 'SUCCESS') {
		$code = 1;
		$msg = '操作成功';
		$sql_set['cashout_outid'] = $json['payment_no'];
		$sql_set['cashout_state'] = 1;		
		$sql_set['cashout_ptime'] = time();		
		$db->pe_update('cashout', array('cashout_id'=>$cashout['cashout_id']), pe_dbhold($sql_set));
	}
	else {
		$code = 0;
		$msg = "{$json['return_msg']} - {$json['err_code_des']}";
	}
	return array('code'=>$code, 'msg'=>$msg);
}

//微信支付退款
function wechat_refund($info) {
	global $db, $pe;
	$wechat_config = wechat_config();
	//$info = $db->pe_select('refund', array('refund_id'=>$refund_id));
	$order = $db->pe_select('order', array('order_id'=>pe_dbhold($info['order_id'])));
	$pay = $db->pe_select('pay', array('pay_id'=>pe_dbhold($order['order_payid'])));	
	//退款接口
	$xml_arr['appid'] = $wechat_config['wxpay_appid'] ? $wechat_config['wxpay_appid'] : $wechat_config['wxpay_minapp_appid'];
	$xml_arr['mch_id'] = $wechat_config['wxpay_mchid'];
	$xml_arr['nonce_str'] = md5(microtime(true).pe_ip().'koyshe+andrea');
	$xml_arr['sign_type'] = 'MD5';
	$xml_arr['transaction_id'] = $pay['order_outid'];
	$xml_arr['out_refund_no'] = $info['refund_id'];
	$xml_arr['total_fee'] = $pay['order_money'] * 100;
	$xml_arr['refund_fee'] = $info['refund_money'] * 100;
	$xml_arr['refund_desc'] = $info['refund_text'];
	$xml_arr['notify_url'] = $wechat_config['refund_url'];
	$xml_arr['sign'] = wechat_sign($xml_arr, $wechat_config['wxpay_apikey']);
	//发送xml下单请求
	$json = wechat_sendxml('https://api.mch.weixin.qq.com/secapi/pay/refund', $xml_arr, true);
	$sql_set['refund_outid'] = $json['refund_id'];
	if ($json['return_code'] == 'SUCCESS' && $json['result_code'] == 'SUCCESS') {
		$sql_set['refund_pstate'] = 'success';
		$sql_set['refund_perror'] = $msg ='';
		$code = 1;
	}
	else {
		$sql_set['refund_pstate'] = 'error';
		$sql_set['refund_perror'] = $msg = "{$json['return_msg']} - {$json['err_code_des']}";
		$code = 0;
	}
	$db->pe_update('refund', array('refund_id'=>$info['refund_id']), pe_dbhold($sql_set));
	return array('code'=>$code, 'msg'=>$msg);
}

//添加微信模板
function wechat_notice_addtpl($tpl_id) {
	$wechat_config = wechat_config();
	$json = wechat_curlpost("https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token={$wechat_config['wechat_access_token']}", array('template_id_short'=>$tpl_id), 'json');
	if ($json['errcode'] == 0) {
		return array('code'=>1, 'id'=>$json['template_id']);
	}
	else {
		return array('code'=>0, 'msg'=>$json['errmsg']);
	}
}

//删除微信模板
function wechat_notice_deltpl($tpl_id) {
	$wechat_config = wechat_config();
	$json = wechat_curlpost("https://api.weixin.qq.com/cgi-bin/template/del_private_template?access_token={$wechat_config['wechat_access_token']}", array('template_id'=>$tpl_id), 'json');
	if ($json['errcode'] == 0) {
		return array('code'=>1);
	}
	else {
		return array('code'=>0, 'msg'=>$json['errmsg']);
	}
}

//发送微信模板通知
function wechat_notice($info) {
	global $db;
	$wechat_config = wechat_config();
	$data = unserialize($info['noticelog_data']);
	$json = wechat_curlpost("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$wechat_config['wechat_access_token']}", $data, 'json');
	if ($json['errcode'] == 0) {
		$sql_set['noticelog_state'] = 'success';
	}
	else {
		$sql_set['noticelog_state'] = 'fail';	
		$sql_set['noticelog_error'] = $json['errmsg'];
	}
	$sql_set['noticelog_stime'] = time();
	$db->pe_update('noticelog', array('noticelog_id'=>$info['noticelog_id']), pe_dbhold($sql_set));
}

//生成微信参数签名(js-sdk)
function wechat_jsapi_config($api_list, $debug = false) {
	$wechat_config = wechat_config();
	$arr['noncestr'] = md5(microtime(true).pe_ip().'koyshe+andrea');
	$arr['jsapi_ticket'] = $wechat_config['wechat_jsapi_ticket'];
	$arr['timestamp'] = time();		
	$arr['url'] = pe_nowurl();
	ksort($arr);	
	$sign = "";
	foreach ($arr as $k => $v) {
		if ($k != "sign" && $v != "" && !is_array($v)){
			$sign .= "{$k}={$v}&";
		}
	}
	$sign = trim($sign, "&");
	$sign = sha1($sign);
	$config_arr['debug'] = $debug;
	$config_arr['appId'] = $wechat_config['wechat_appid'];
	$config_arr['timestamp'] = $arr['timestamp'];
	$config_arr['nonceStr'] = $arr['noncestr'];
	$config_arr['signature'] = $sign;
	$config_arr['jsApiList'] = explode('|', $api_list);
	return "wx.config(".json_encode($config_arr).")";
};

//检测是否关注公众号
function wechat_check_follow($user = array()) {
	global $db;
	$wechat_config = wechat_config();
	$json = wechat_curlget("https://api.weixin.qq.com/cgi-bin/user/info?access_token={$wechat_config['wechat_access_token']}&openid={$user['user_wx_openid']}&lang=zh_CN");
	$json = json_decode($json, true);
	if ($json['errcode']) return false;
	if ($json['subscribe']) {
		user_follow_callback($user, 1);
	}
	else {
		user_follow_callback($user, 0);
	}
}

//获取小程序码
function minapp_qrcode($url, $arg = '', $color_arr = null) {
	global $pe;
	$wechat_config = wechat_config();
	$qrcode_name = md5($url.$arg);
	$qrcode_file = "{$pe['path']}data/attachment/qrcode/{$qrcode_name}.png";
	$qrcode_url = "data/attachment/qrcode/{$qrcode_name}.png";
	if (is_file($qrcode_file)) return array('code'=>1, 'qrcode'=>$qrcode_url);
	$json_arr['page'] = $url;
	$json_arr['scene'] = $arg;
	$json_arr['auto_color'] = false;
	if (is_array($color_arr)) $json_arr['line_color'] = json_decode(json_encode($color_arr));
	$json = pe_curl_post("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$wechat_config['minapp_access_token']}", $json_arr, 'json');
	$arr = json_decode($json, true);
	if (is_array($arr)) {
		return array('code'=>0, 'msg'=>"{$arr['errcode']}:{$arr['errmsg']}");
	}
	else {
		file_put_contents($qrcode_file, $json);
		return array('code'=>1, 'qrcode'=>$qrcode_url);		
	}
}

//小程序隐私数据解密获得手机号
function minapp_data_jiemi($data, $iv, $session_key) {
	$wechat_config = wechat_config();
	if (strlen($session_key) != 24) {
		return array('code'=>0, 'msg'=>"session_key error");
	}
	if (strlen($iv) != 24) {
		return array('code'=>0, 'msg'=>"iv error");
	}	
	$result = openssl_decrypt(base64_decode($data), "AES-128-CBC", base64_decode($session_key), 1, base64_decode($iv));
	$json = json_decode($result, true);
	if ($json == NULL) {
		return array('code'=>0, 'msg'=>"解码失败");
	}
	return array('code'=>1, 'data'=>$json);
}

function minapp_livepushurl($domain = 'livepush.phpshe.com', $stream_name = 'minapp', $key = '80f24da1341e17ebef8c20c4b5d6292e', $time = '') {
	if ($key && $time){
	    $txTime = strtoupper(base_convert(strtotime($time),10,16));
	    //txSecret = MD5( KEY + streamName + txTime )
	    $txSecret = md5($key.$stream_name.$txTime);
	    $ext_str = "?".http_build_query(array(
	          "txSecret"=> $txSecret,
	          "txTime"=> $txTime
	    ));
	}
	return "rtmp://".$domain."/live/".$stream_name . (isset($ext_str) ? $ext_str : "");
}

function minapp_dwz($url = '') {
	global $db;
	$info = $db->pe_select('dwz', array('dwz_url'=>$url));
	if ($info['dwz_id']) {
		return $info['dwz_id'];
	}
	else {
		return $db->pe_insert('dwz', array('dwz_url'=>$url, 'dwz_atime'=>time()));
	}
}
?>